package com.matrix.draft.sockettest.newprotocoltcp.handler;

import com.matrix.draft.sockettest.newprotocoltcp.pojo.MyMessage;
import com.matrix.draft.sockettest.newprotocoltcp.util.MyUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.extern.slf4j.Slf4j;

/**
 * 编码器
 */
@Slf4j
public class NewProtocolEncoder extends MessageToByteEncoder<MyMessage> {
    @Override
    protected void encode(ChannelHandlerContext ctx, MyMessage msg, ByteBuf out) throws Exception {
        /** 根据协议按顺序依次写入ByteBuf里面(注意writeInt和writeByte的使用) **/
        // 魔数 (判定数据包是否是符合标准的有效的, 4b)
        // 版本号 (可以支持协议升级, 1b)
        // 序列化算法 (json,protobuf,hessian,jdk, 4b)
        // 指令类型 (例如登录,注册,群聊,私聊等业务相关, 4b)
        // 请求序号 (为了双工通信提供异步能力, 4b)
        // ###如果前面的字段的长度加起来不是2的倍数,这里再writeByte(0xff)一个字节(无意义)###
        // 正文长度字段 (4b)
        // 正文
        out.writeInt(msg.getMagicNum());
        out.writeByte(msg.getVersion());
        out.writeInt(msg.getSerializationType());
        out.writeInt(msg.getAffairType());
        out.writeInt(msg.getSequenceId());
        out.writeByte(0xff); // 由于头信息字节数不是偶数,这里+1个无意义字节,符合规范
        // 根据affairType来决定用str2Bytes还是obj2Bytes

        byte[] bytes;
        switch (msg.getAffairType()) {
            // 1:STRING
            default:
            case 1: {
                bytes = MyUtil.str2Bytes((String) msg.getContent());
                break;
            }
        }
        out.writeInt(bytes.length);
        out.writeBytes(bytes);
        log.debug("Encoded");
    }
}
